package top.hmtools.jsCss.common;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import top.hmtools.base.CharsetGuessTools;
import top.hmtools.base.StringTools;

public class CommonTools {
	
	private static Logger logger = LoggerFactory.getLogger(CommonTools.class);
	
	private static List<String> readedJarFiles = new ArrayList<>();

	/**
	 * 从指定资源读取指定后缀的内容到字典中。
	 * @param resources	资源集合
	 * @param repertory	字典
	 * @param suffix	后缀
	 */
	public static void loadContent(String encoding,Enumeration<URL> resources,Map<String,String> repertory, String... suffixes){
		if(resources == null || !resources.hasMoreElements() || suffixes == null || suffixes.length<1){
			return;
		}
		while(resources.hasMoreElements()){
			URL urlRes = resources.nextElement();
			String urlResStr = urlRes.toString();
			logger.info("从{}加载静态资源。。。",urlResStr);
			if(urlResStr.toUpperCase().startsWith("JAR")){
				JarFile jarFile=null;
				try {
					//资源是jar包
					String[] urlResArr = urlResStr.split("!/");
					URL jarFileURL = new URL(urlResArr[0].replaceFirst("jar:", "")+"/");
					
					//检测是否已经加载过
					String key = jarFileURL.toString().toUpperCase()+Arrays.toString(suffixes).toUpperCase();
					if(readedJarFiles.contains(key)){
						logger.info("已从jarFileURL（{}）加载过静态资源。。。 ",jarFileURL);
						continue;
					}else{
						readedJarFiles.add(key);
						logger.info("jarFileURL >> "+jarFileURL);
					}
					
					//尝试读取
					URI uri = jarFileURL.toURI();
					logger.info("uri >>> "+uri);
					File file = new File(uri);
					jarFile = new JarFile(file);//项目根jar包（里面会包含依赖的子jar包）
					Enumeration<JarEntry> entries = jarFile.entries();
					while(entries.hasMoreElements()){
						JarEntry jarEntry = entries.nextElement();//根jar包中的内容
						String name = jarEntry.getName();
						//jar包中的jar包
						if(name.toUpperCase().endsWith("JAR")){
							logger.debug("尝试从{}中读取静态资源。。。",name);
							InputStream inputStream = jarFile.getInputStream(jarEntry);
							JarInputStream jis = new JarInputStream(inputStream);
							JarEntry subJarEntry = null;//根jar包中jar包中的内容
							while((subJarEntry = jis.getNextJarEntry())!=null){
								String subName = subJarEntry.getName();
								for(String suffix:suffixes){
									if(subName.toUpperCase().endsWith(suffix.toUpperCase())){
										//猜测原始文件字符编码
										byte[] byteArray = IOUtils.toByteArray(jis);
										String guessedEncoding = CharsetGuessTools.doGuess(byteArray);
										if(StringTools.isBlank(guessedEncoding)){
											guessedEncoding=encoding;
										}
										String content = new String(byteArray, guessedEncoding);
										//存入缓存
										repertory.put(FilenameUtils.getName(subName).toLowerCase(), content);
										logger.debug("成功添加资源内容，猜测文件{}的字符编码为：{}，内容摘要有：{}",subName,guessedEncoding,(StringTools.isBlank(content)?"":content.length()<20?content:content.substring(0, 20)+"..."));
										break;
									}
								}
							}
							continue;
						}
						//jar包中的静态资源
						for(String suffix:suffixes){
							if(name.toUpperCase().endsWith(suffix.toUpperCase())){
								InputStream inputStream = jarFile.getInputStream(jarEntry);
								//猜测原始文件字符编码
								byte[] byteArray = IOUtils.toByteArray(inputStream);
								String guessedEncoding = CharsetGuessTools.doGuess(byteArray);
								if(StringTools.isBlank(guessedEncoding)){
									guessedEncoding=encoding;
								}
								String content = new String(byteArray, guessedEncoding);
								//存入缓存
								repertory.put(FilenameUtils.getName(name).toLowerCase(), content);
								logger.debug("成功添加资源内容，猜测文件{}的字符编码为：{}，内容摘要有：{}",name,guessedEncoding,(StringTools.isBlank(content)?"":content.length()<20?content:content.substring(0, 20)+"..."));
								break;
							}
						}
					}
				} catch (Exception e) {
					logger.error("从"+urlResStr+"加载静态资源。。。"+e.getMessage(),e);
				}finally{
					try {
						if(jarFile!=null){
							jarFile.close();
						}
					} catch (IOException e) {
						logger.error(e.getMessage(),e);
					}
				}
			}else if(urlResStr.toUpperCase().startsWith("FILE")){
				//资源是文件夹
				try {
					String fileStr = urlRes.getFile();
					File file = new File(fileStr);
					//如果资源是文件夹
					if(file.isDirectory()){
						Collection<File> listFiles = FileUtils.listFiles(file, suffixes, true);
						for(File tmp:listFiles){
							String name = tmp.getName();
							byte[] byteArray = FileUtils.readFileToByteArray(tmp);
							String guessedEncoding = CharsetGuessTools.doGuess(byteArray);
							if(StringTools.isBlank(guessedEncoding)){
								guessedEncoding=encoding;
							}
							String content = new String(byteArray, guessedEncoding);
							//存入缓存
							repertory.put(FilenameUtils.getName(name).toLowerCase(), content);
							logger.debug("成功添加资源内容，猜测文件{}的字符编码为：{}，内容摘要有：{}",name,guessedEncoding,(StringTools.isBlank(content)?"":content.length()<20?content:content.substring(0, 20)+"..."));
						}
					}else{
						//如果资源是单个文件
						for(String suffix:suffixes){
							String name = file.getName();
							if(name.toUpperCase().endsWith(suffix.toUpperCase())){
								byte[] byteArray = FileUtils.readFileToByteArray(file);
								String guessedEncoding = CharsetGuessTools.doGuess(byteArray);
								if(StringTools.isBlank(guessedEncoding)){
									guessedEncoding=encoding;
								}
								String content = new String(byteArray, guessedEncoding);
								//存入缓存
								repertory.put(FilenameUtils.getName(name).toLowerCase(), content);
								logger.debug("成功添加资源内容，猜测文件{}的字符编码为：{}，内容摘要有：{}",name,guessedEncoding,(StringTools.isBlank(content)?"":content.length()<20?content:content.substring(0, 20)+"..."));
								break;
							}
						}
					}
				} catch (Exception e) {
					logger.error("从"+urlResStr+"加载静态资源。。。"+e.getMessage(),e);
				}
			}
		}
	}
}
